package com.zq.it.service.impl.exam;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.struts2.ServletActionContext;

import com.zq.it.dao.common.PageConfig;
import com.zq.it.pojo.Student;
import com.zq.it.pojo.TClass;
import com.zq.it.pojo.Teacher;
import com.zq.it.pojo.exam.TClassPaper;
import com.zq.it.pojo.exam.TExam;
import com.zq.it.pojo.exam.TExamResult;
import com.zq.it.pojo.exam.TOptions;
import com.zq.it.pojo.exam.TPaper;
import com.zq.it.pojo.exam.TPaperDetail;
import com.zq.it.pojo.exam.TPaperSection;
import com.zq.it.pojo.exam.data.ObjectData;
import com.zq.it.pojo.exam.data.PaperData;
import com.zq.it.service.common.BaseServiceImpl;
import com.zq.it.service.exam.PaperService;
import com.zq.it.tool.Constant;
import com.zq.it.tool.StringUtil;

public class PaperServiceImpl extends BaseServiceImpl implements PaperService {

	@Override
	public void addPaper(Teacher teacher, TPaper paper, String[] rand_cname,
			String[] rand_dbid, String[] rand_nums, String[] rand_perscore,
			String[] rand_qtype) {
		paper.setTeacher(teacher);
		paperDAO.save(paper);
		TPaperSection section = null;
		for (int i = 0; i < rand_cname.length; i++) {
			section = new TPaperSection();
			section.setPerScore(Integer.parseInt(rand_perscore[i]));
			section.setSectionName(rand_cname[i]);
			section.setTPaper(paper);
			paperSectionDAO.save(section);
			section = null;
		}
	}

	@Override
	public TPaper getPaperById(String id, Teacher teacher) {
		TPaper paper = null;
		paper = paperDAO.findById(Long.parseLong(id));
		if (paper.getTeacher().getId() == teacher.getId()) {
			return paper;
		} else {
			return null;
		}
	}

	@Override
	public TPaper getPaperById(String id) {
		return paperDAO.findById(Long.parseLong(id));
	}

	@Override
	public void updatePaper(Teacher teacher, TPaper paper, String[] rand_cname,
			String[] rand_dbid, String[] rand_nums, String[] rand_perscore,
			String[] rand_qtype) {
		TPaper entity = paperDAO.findById(paper.getId());
		if (entity.getTeacher().getId() == teacher.getId()) {
			List temp = null;
			temp = paperDetailDAO.findByHql(
					"from TPaperDetail t where t.TPaper.id=" + paper.getId());

			if (null != temp && temp.size() > 0)
				throw new RuntimeException();

			temp = classPaperDAO.findByHql(
					"from TClassPaper t where t.TPaper.id=" + paper.getId());
			if (null != temp && temp.size() > 0)
				throw new RuntimeException();
			entity.setEndTime(paper.getEndTime());
			entity.setMinute(paper.getMinute());
			entity.setPName(paper.getPName());
			entity.setPostDate(paper.getPostDate());
			entity.setStartTime(paper.getStartTime());
			paperDAO.update(entity);
			paperSectionDAO.deleteByHql(
					"delete from TPaperSection model where model.TPaper.id = '"
							+ paper.getId() + "'");
			TPaperSection section = null;
			for (int i = 0; i < rand_cname.length; i++) {
				section = new TPaperSection();
				section.setPerScore(Integer.parseInt(rand_perscore[i]));
				section.setSectionName(rand_cname[i]);
				section.setTPaper(paper);
				paperSectionDAO.save(section);
				section = null;
			}
		}
	}

	@Override
	public List getPaperDetails(TPaper paper, Teacher teacher) {
		if (paper.getTeacher().getId() == teacher.getId()) {
			return getPaperDetails(paper.getId());
		}
		return null;
	}

	@Override
	public List<TPaperDetail> getPaperDetails(long paperId) {
		List<TPaperDetail> data = paperDetailDAO
				.findByHql("from TPaperDetail model where model.TPaper.id = '"
						+ paperId + "' order by orderId");
		for (TPaperDetail detail : data) {
			detail.setTPaperSection(paperSectionDAO
					.findById(detail.getTPaperSection().getId()));
			detail.setTQuestions(
					questionsDAO.findById(detail.getTQuestions().getId()));
			if (detail.getTQuestions().getQType() == Constant.QTYPE_SELECT) {
				List<TOptions> options = optionsDAO
						.findByHql("from TOptions t where t.TQuestions.id = "
								+ detail.getTQuestions().getId()
								+ " order by t.OId");
				Set optionSet = new LinkedHashSet();
				for (TOptions option : options) {
					optionSet.add(option);
				}
				detail.getTQuestions().setTOptionses(optionSet);
			}
		}
		return data;
	}

	@Override
	public List getPaperSections(long id) {
		List data = null;
		data = paperSectionDAO.findByHql(
				"from TPaperSection model where model.TPaper.id = " + id);
		return data;
	}

	@Override
	public String createQuestionHql(Teacher teacher, String[] rand_cname,
			String[] rand_dbid, String[] rand_qtype) {
		if (!StringUtil.isEmpty(rand_cname[0])) {
			try {
				rand_cname[0] = URLDecoder.decode(rand_cname[0],
						Constant.UTF_8);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		StringBuffer hql = new StringBuffer(
				"from TQuestions as model where 1=1");
		String cnameHql = null == rand_cname[0] || "".equals(rand_cname[0])
				? ""
				: " and model.content like '%" + rand_cname[0] + "%'";
		String dbHql = null == rand_dbid[0] || "".equals(rand_dbid[0])
				? ""
				: " and model.TQuestionDb.id =" + rand_dbid[0];
		String qtypeHql = null == rand_qtype[0] || "".equals(rand_qtype[0])
				? ""
				: " and model.QType=" + rand_qtype[0];
		String teacherHql = " and model.Teacher.id =" + teacher.getId();
		hql.append(cnameHql).append(dbHql).append(qtypeHql).append(teacherHql);
		return hql.toString();
	}

	@Override
	public boolean updatePaperDetail(Teacher teacher, long id, String[] sid,
			String[] qid, String[] qscore) {
		boolean flag = false;
		TPaper paper = paperDAO.findById(id);

		if (paper.getTeacher().getId() == teacher.getId())

		{
			TPaperDetail detail = null;
			int totalScore = 0;
			paperDetailDAO.deleteByHql(
					"delete from TPaperDetail detail where detail.TPaper.id="
							+ id);
			for (int i = 0; i < sid.length; i++) {
				detail = new TPaperDetail();
				detail.setOrderId(i);
				detail.setScore(Integer.parseInt(qscore[i]));
				detail.setTPaper(paper);
				detail.setTPaperSection(
						paperSectionDAO.findById(Long.parseLong(sid[i])));
				detail.setTQuestions(
						questionsDAO.findById(Long.parseLong(qid[i])));
				totalScore = Integer.parseInt(qscore[i]) + totalScore;
				paperDetailDAO.save(detail);
			}
			paper.setTotalScore(totalScore);
			paperDAO.save(paper);
			flag = true;
		}
		return flag;
	}

	@Override
	public PaperData getPaperData(Teacher teacher, long id) {
		PaperData data = null;
		TPaper paper = paperDAO.findById(id);
		if (paper.getTeacher().getId() == teacher.getId()) {
			data = new PaperData();
			data.setPaper(paper);
			data.setPaperDetail(getPaperDetails(id));
			data.setPaperSections(getPaperSections(id));
		}
		return data;
	}

	@Override
	public ObjectData getAssignClass(PageConfig config) {
		ObjectData data = getListByPage(config);
		List<TClassPaper> list = data.getList();
		for (TClassPaper classPaper : list) {
			classPaper.setTClass(getClassDao()
					.findById(classPaper.getTClass().getClassId()));
		}
		return data;
	}

	@Override
	public void addClassAssign(String[] ids, long paperId, Teacher teacher) {
		TPaper paper = paperDAO.findById(paperId);
		if (paper.getTeacher().getId() == teacher.getId()) {
			List<TClassPaper> listCP = null;
			for (String id : ids) {
				listCP = classPaperDAO.findByHql(
						"from TClassPaper tcp where tcp.TClass.classId=" + id
								+ " and tcp.TPaper.id=" + paper.getId());
				if (listCP.size() > 0)
					continue;
				TClass tclass = getClassDao().findById(Integer.parseInt(id));
				TClassPaper classPaper = new TClassPaper(tclass, paper, null);
				classPaperDAO.save(classPaper);
				List<Student> students = getStudentDao()
						.findByClassId(tclass.getClassId());
				TExamResult examResult = null;
				for (Student student : students) {
					examResult = new TExamResult(student, paper.getId(), 0, 0,
							null);
					examResultDAO.save(examResult);
				}
			}
		} else {
			throw new RuntimeException("作死！");
		}
	}

	@Override
	public PaperData getPaperData(Student student, long id) {
		PaperData data = null;
		TExamResult result = examResultDAO.findById(id);
		long stuId = result.getStudent().getId();
		if (stuId == student.getId()) {
			data = new PaperData();
			TPaper paper = paperDAO.findById(result.getPId());
			data.setPaper(paper);
			data.setPaperDetail(getPaperDetails(result.getPId()));
			data.setPaperSections(getPaperSections(result.getPId()));
		}
		return data;
	}

	@Override
	public ObjectData getExamClassList(PageConfig config) {
		ObjectData data = getListByPage(config);
		List<TClassPaper> list = data.getList();
		for (TClassPaper classPaper : list) {
			classPaper.setTClass(getClassDao()
					.findById(classPaper.getTClass().getClassId()));
			classPaper.setTPaper(
					paperDAO.findById(classPaper.getTPaper().getId()));
		}
		return data;
	}

	@Override
	public TClassPaper findClassPaperById(String id) {
		return classPaperDAO.findById(Long.parseLong(id));
	}

	@Override
	public TClassPaper findClassPaperById(String id, Teacher teacher) {
		TClassPaper classPaper = findClassPaperById(id);
		classPaper.setTPaper(paperDAO.findById(classPaper.getTPaper().getId()));
		classPaper.setTClass(
				getClassDao().findById(classPaper.getTClass().getClassId()));
		if (classPaper.getTPaper().getTeacher().getId() == teacher.getId()) {
			return classPaper;
		}
		return null;
	}

	@Override
	public ObjectData getStudentExamRelList(PageConfig config) {
		ObjectData data = super.getListByPage(config);
		List<TExamResult> list = data.getList();
		for (TExamResult examResult : list) {
			examResult.setStudent(
					getStudentDao().findById(examResult.getStudent().getId()));
		}
		return data;
	}

	@Override
	public Map getPaperResultDetail(Teacher teacher, String id) {
		List<TExam> data = null;
		Map map = null;
		TExamResult examResult = examResultDAO.findById(Long.parseLong(id));
		TPaper paper = paperDAO.findById(examResult.getPId());
		if (paper.getTeacher().getId() != teacher.getId()) {
			return null;
		}
		data = examDAO.findByHql("from TExam exam where exam.TPaper.id ="
				+ paper.getId() + " and exam.Student.id="
				+ examResult.getStudent().getId() + "");
		map = new HashMap();
		map.put("paper_id", paper.getId());
		map.put("student_id", examResult.getStudent().getId());
		map.put("exam_result_id", examResult.getId());
		map.put("student_total_score", examResult.getScore());
		for (TExam exam : data) {
			map.put(exam.getTPaper().getId() + "_"
					+ exam.getTQuestions().getId(), exam);
		}
		if (null == data || data.size() == 0) {
			map.put("data_check", false);
		} else {
			map.put("data_check", true);
		}
		return map;
	}

	@Override
	public String updateStudentScore(long pid, Long uid, String qid,
			Long examResultId, Long score, Teacher teacher) {
		TPaper paper = paperDAO.findById(pid);
		if (paper.getTeacher().getId() != teacher.getId())
			return "error";
		List list = examDAO.findByHql("from TExam exam where exam.Student.id="
				+ uid + " and exam.TPaper.id=" + pid
				+ " and exam.TQuestions.id=" + qid + "");
		if (null == list || list.size() != 1)
			return "error";
		TExam exam = (TExam) list.get(0);
		exam.setScore(Integer.parseInt(score + ""));
		TExamResult examResult = examResultDAO.findById(examResultId);
		examResult.setScore(Integer.parseInt("" + examDAO
				.findByHql(
						"select sum(exam.score) from TExam exam where exam.Student.id="
								+ uid + " and exam.TPaper.id=" + pid)
				.listIterator().next()));
		examDAO.update(exam);
		examResultDAO.update(examResult);
		return "1";
	}

	@Override
	public String createPaperHql(TPaper paper, Teacher teacher) {
		StringBuffer hql = new StringBuffer("from TPaper p where 1=1 ");
		String pNameHql = null == paper.getPName()
				|| "".equals(paper.getPName())
						? " "
						: " and p.PName like '%" + paper.getPName() + "%'";
		hql.append(pNameHql);
		return hql.toString();
	}

	@Override
	public String deletePaper(Teacher teacher, String[] ids) {
		TPaper paper = null;
		List temp;
		File file = null;
		for (String id : ids) {
			paper = paperDAO.findById(Long.parseLong(id));
			if (null == paper)
				return "false";
			if (teacher.getId() != paper.getTeacher().getId())
				return "false";
			temp = classPaperDAO
					.findByHql(" from TClassPaper t where t.TPaper.id = " + id);
			if (null != temp && temp.size() > 0)
				return "false";
			paperDetailDAO.deleteByHql(
					"delete from TPaperDetail t where t.TPaper.id=" + id);
			paperSectionDAO.deleteByHql(
					"delete from TPaperSection t where t.TPaper.id=" + id);
			file = new File(ServletActionContext.getServletContext()
					.getRealPath(Constant.PAPER_EXPORT + "_" + paper.getId()
							+ ".doc"));
			deleteDir(file);
			paperDAO.delete(paper);
		}
		return "ok";
	}

	@Override
	public String createExamClassListHql(TClassPaper classPaper,
			String startTime, String endTime, Teacher teacher) {
		StringBuffer hql = new StringBuffer(
				"from TClassPaper as model where model.TPaper.Teacher.id="
						+ teacher.getId());
		String paperNameHql = null == classPaper.getTPaper().getPName()
				|| "".equals(classPaper.getTPaper().getPName())
						? ""
						: " and model.TPaper.PName like '%"
								+ classPaper.getTPaper().getPName() + "%'";
		String classHql = classPaper.getTClass().getClassId() <= 0
				? ""
				: " and model.TClass.id=" + classPaper.getTClass().getClassId();
		String startTimeHql = null == startTime || "".equals(startTime)
				? ""
				: " and model.TPaper.postDate >= '" + startTime + "'";
		String endTimeHql = null == endTime || "".equals(endTime)
				? ""
				: " and model.TPaper.postDate <= '" + endTime + "'";
		String orderHql = " order by model.TPaper.postDate";
		hql.append(paperNameHql).append(classHql).append(startTimeHql)
				.append(endTimeHql).append(orderHql);
		return hql.toString();
	}

	@Override
	public String deleteExamClassList(Teacher teacher, String[] ids) {
		TClassPaper classPaper = null;
		TPaper paper = null;
		for (String id : ids) {
			classPaper = classPaperDAO.findById(Long.parseLong(id));
			paper = paperDAO.findById(classPaper.getTPaper().getId());
			if (paper.getTeacher().getId() != teacher.getId())
				return "fasle";
			examDAO.deleteByHql(
					"delete from TExam t where t.TPaper.id=" + paper.getId()
							+ " and exists(select 1 from Student stu where stu.id = t.Student.id and stu.tclass.classId="
							+ classPaper.getTClass().getClassId() + ")");
			examResultDAO.deleteByHql(
					"delete from TExamResult t where t.PId=" + paper.getId()
							+ " and exists(select 1 from Student stu where stu.id = t.student.id and stu.tclass.classId="
							+ classPaper.getTClass().getClassId() + ")");
			classPaperDAO
					.deleteByHql("delete from TClassPaper t where t.TPaper.id="
							+ paper.getId() + " and t.TClass.classId="
							+ classPaper.getTClass().getClassId());
		}
		return "ok";
	}

	@Override
	public String creatExamResultListHql(TExamResult examResult, TClassPaper classPaper) {
		StringBuffer hql = new StringBuffer("from TExamResult as t where t.PId="
				+ classPaper.getTPaper().getId() + " and t.student.tclass.classId="
				+ classPaper.getTClass().getClassId());
		String stuNameHql = "".equals(examResult.getStudent().getStuName())
				? ""
				: " and t.student.stuName like '%"
						+ examResult.getStudent().getStuName() + "%'";
		String studentNoHql = null == examResult.getStudent().getStuId()
				? ""
				: " and t.student.stuId like '%"
						+ examResult.getStudent().getStuId() + "%'";
		hql.append(stuNameHql).append(studentNoHql);
		return hql.toString();
	}
}
